#pragma once

#include <memory>
#include <unordered_map>
#include <boost/asio.hpp>
#include <boost/log/trivial.hpp>

namespace net_channel {
namespace server {

class Connection : public std::enable_shared_from_this<Connection> {
public:
    explicit Connection(boost::asio::ip::tcp::socket socket)
        : socket_(std::move(socket)) {}

    void start() {
        do_read();
    }

private:
    void do_read() {
        auto self = shared_from_this();
        socket_.async_read_some(boost::asio::buffer(buffer_),
            [this, self](boost::system::error_code ec, std::size_t length) {
                if (!ec) {
                    // TODO: Handle received data
                    do_read();
                } else {
                    BOOST_LOG_TRIVIAL(error) << "Read failed: " << ec.message();
                }
            });
    }

    boost::asio::ip::tcp::socket socket_;
    std::array<char, 8192> buffer_;
};

class ConnectionManager {
public:
    void start(std::shared_ptr<Connection> conn) {
        connections_.insert(conn);
        conn->start();
    }

    void stop(std::shared_ptr<Connection> conn) {
        connections_.erase(conn);
    }

    void stop_all() {
        connections_.clear();
    }

private:
    std::unordered_set<std::shared_ptr<Connection>> connections_;
};

} // namespace server
} // namespace net_channel